package com.jiepos.mpos.pay.quickpay.service.huiepay;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import com.hy.pmp.client.DefaultQuickPayClient;
import com.hy.utils.JsonUtil;
import com.hy.utils.StringUtil;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.core.util.DateUtil;
import com.jiepos.mpos.core.util.GlobalUtils;
import com.jiepos.mpos.core.util.MathUtils;
import com.jiepos.mpos.core.util.StringUtils;
import com.jiepos.mpos.pay.CommonService;
import com.jiepos.mpos.pay.quickpay.service.AtrPayService;
import com.jiepos.mpos.pay.quickpay.service.IQuickPayService;

@Service("HUIEPAY_TERM")
public class HuiePayApiService extends AtrPayService implements IQuickPayService {
	private static final Logger _log = LoggerFactory.getLogger(HuiePayApiService.class);
	private static String serviceUrl = GlobalUtils.getPayConfProperty("huiepay.pay.serviceUrl");
	private static String version = GlobalUtils.getPayConfProperty("huiepay.pay.version");
	private static String privateKeyPath = GlobalUtils.getPayConfProperty("huiepay.pay.privateKeyPath");
	private static String publicKeyPath = GlobalUtils.getPayConfProperty("huiepay.pay.publicKeyPath");
	private static DefaultQuickPayClient client = new DefaultQuickPayClient(version, SystemConstant.UTF_ENCODING,
			privateKeyPath, publicKeyPath);

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Override
	public Map payOrder(String channelMchntCd, String orderNo, String orderAmt, String mobile, String certNo,
			String userName, String cardNo, String remark, Map dataMap) {
		try {
			Map<String, Object> traceTime = mainBusinessService.getSystemTime();
			dataMap.put("loc_dt", traceTime.get("loc_dt"));// 交易日期
			dataMap.put("loc_ts", traceTime.get("loc_ts"));// 交易时间
			Map<String, String> reqMap = new HashMap<String, String>();
			reqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
			Map<String, Object> data = getChannelBankcard(dataMap);
			String msgBody = null;
			if (!StringUtils.isEmpty(data)) {
				String user_agree_id = String.valueOf(data.get("user_agree_id"));
				String pay_agree_id = String.valueOf(data.get("pay_agree_id"));
				msgBody = AssembleBusiness.assemble1231MsgBody(dataMap, user_agree_id, pay_agree_id);
			} else {
				msgBody = AssembleBusiness.assemble1221MsgBody(client, dataMap);
			}
			String responseBody = client.execute(serviceUrl, msgBody);
			if (StringUtil.isEmpty(responseBody)) {
				reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
				reqMap.put("rspmsg", SystemConstant.RSPCODE_ERROR_MSG);
			} else {
				Map<String, Object> kv = (Map<String, Object>) JsonUtil.fromJsonToObj(responseBody, Map.class);
				reqMap.put("rspcode", String.valueOf(kv.get("resp_cd")));
				reqMap.put("rspmsg", String.valueOf(kv.get("resp_msg")));
			}
			reqMap.put("loc_dt", String.valueOf(traceTime.get("loc_dt")));// 交易日期
			reqMap.put("loc_ts", String.valueOf(traceTime.get("loc_ts")));// 交易时间
			return getStandardData(reqMap);
		} catch (Exception e) {
			_log.error("上海汇宜支付[{}]会员[{}]发生异常![{}]", dataMap.get("custom_no"), dataMap.get("loc_trace_no"), e);
			return null;
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public Map<String, String> sendVerifyCode(Map<String, String> dataMap) {
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
		reqMap.put("loc_dt", dataMap.get("loc_dt"));// 交易日期
		reqMap.put("loc_ts", dataMap.get("loc_ts"));// 交易时间
		try {
			String msgBody = AssembleBusiness.assemble1241MsgBody(client, dataMap);
			String responseBody = client.execute(serviceUrl, msgBody);
			// 3.交易异常时获取错误信息
			if (StringUtil.isEmpty(responseBody)) {
				reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
				reqMap.put("rspmsg", SystemConstant.RSPCODE_ERROR_MSG);
			} else {
				Map<String, Object> kv = (Map<String, Object>) JsonUtil.fromJsonToObj(responseBody, Map.class);
				reqMap.put("rspcode", String.valueOf(kv.get("resp_cd")));
				reqMap.put("rspmsg", String.valueOf(kv.get("resp_msg")));
			}
			return getStandardData(reqMap);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public boolean noticeOrder(Map<String, String> paramMap) {
		_log.info("上海汇宜异步通知原始数据map=[{}]",paramMap);
		Map<String, String> standardMap = noticeStandard(paramMap);
		boolean flag = false;
		try {
			flag = noticeService.noticeUpdate(standardMap);
		} catch (Exception e) {
			flag = false;
			_log.error("上海汇宜异步通知更新发生异常", e);
		}
		return flag;
	}

	@Override
	public Map<String, String> queryChannelOrder(Map<String, String> queryMap) {
		_log.info("上海汇宜主动查询请求的map[{}]", queryMap);
		try {

			Map<String, Object> repMap = new HashMap<String, Object>();

			// 2.组装Json字符串格式的报文体
			String msgBody = AssembleBusiness.assemble5091MsgBody(queryMap);// 2.2.1
			// 交易状态查询类交易-5091
			// 3.发送交易
			String responseBody = client.execute(serviceUrl, msgBody);

			// 3.交易异常时获取错误信息
			if (StringUtil.isEmpty(responseBody)) {
				repMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
				repMap.put("rspmsg", SystemConstant.RSPCODE_ERROR_MSG);
			} else {
				Map<String, Object> kv = (Map<String, Object>) JsonUtil.fromJsonToObj(responseBody, Map.class);
				repMap = kv;
			}
			return queryStandard(repMap, queryMap.get("loc_trace_no"));
		} catch (Exception e) {
			_log.error("上海汇宜主动查询请求发生异常", e);
			return new HashMap<String, String>();
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, String> verifyCode(Map<String, String> dataMap) {
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
		reqMap.put("loc_dt", dataMap.get("loc_dt"));// 交易日期
		reqMap.put("loc_ts", dataMap.get("loc_ts"));// 交易时间
		try {
			String msgBody = AssembleBusiness.assemble1251MsgBody(client, dataMap);
			String responseBody = client.execute(serviceUrl, msgBody);
			// 3.交易异常时获取错误信息
			if (StringUtil.isEmpty(responseBody)) {
				reqMap.put("rspcode", SystemConstant.RSPCODE_ERROR);
				reqMap.put("rspmsg", SystemConstant.RSPCODE_ERROR_MSG);
			} else {
				Map<String, Object> kv = (Map<String, Object>) JsonUtil.fromJsonToObj(responseBody, Map.class);
				reqMap.put("rspcode", String.valueOf(kv.get("resp_cd")));
				reqMap.put("rspmsg", String.valueOf(kv.get("resp_msg")));
				if (SystemConstant.RSPCODE_SUCCESS.equals(String.valueOf(kv.get("resp_cd")))) {
					String user_agree_id = String.valueOf(kv.get("user_agree_id"));
					String pay_agree_id = String.valueOf(kv.get("pay_agree_id"));
					Map<String, Object> data = getChannelBankcard(dataMap);
					if (StringUtils.isEmpty(data)) {
						saveChannelBankcard(dataMap, user_agree_id, pay_agree_id);
					}
				}
			}
			return getStandardData(reqMap);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public Map<String, String> queryChannelStlResult(
			Map<String, String> queryMap) {
		return null;
	}
	
	@Override
	public Map<String, String> getStandardData(Map<String, String> reqMap) throws Exception{
		Map<String, String> respMap = new HashMap<String, String>();
		Assert.notNull(reqMap.get("loc_trace_no"));
		Map<String, String> infoMap = appLogTransJnlsPayService.getTranInfo(reqMap.get("loc_trace_no"));
		log.info("上海汇宜支付响应报文为:[{}],[{}]交易对应的查询数据为:[{}]",reqMap,reqMap.get("loc_trace_no"),infoMap);
		respMap.put("loc_dt", reqMap.get("loc_dt"));//交易日期
		respMap.put("loc_ts",reqMap.get("loc_ts"));//交易时间
		respMap.put("trf_mchnt_cd", infoMap.get("trf_mchnt_cd"));// 商户编号（渠道）
		respMap.put("trf_term_id", infoMap.get("trf_term_id"));// 终端编号（渠道）
		respMap.put("complete_dt", reqMap.get("complete_dt"));// 订单完成日期（渠道）
		respMap.put("complete_ts", reqMap.get("complete_ts"));// 订单完成时间
		respMap.put("custom_no", infoMap.get("custom_no"));// 客户编号（支付系统）
		respMap.put("term_id", reqMap.get("term_id"));// 本地流水号（支付系统)
		respMap.put("trf_trace_no", reqMap.get("trf_trace_no"));// 渠道方流水号（渠道）
		respMap.put("loc_trace_no", reqMap.get("loc_trace_no"));
		respMap.put("trs_stat", reqMap.get("trs_stat"));// 交易状态
		respMap.put("stlst", infoMap.get("stlst"));// 清算状态
		respMap.put("midfee", infoMap.get("midfee"));// 商户手续费
		respMap.put("stl_amt", reqMap.get("stl_amt"));// 结算金额
		respMap.put("rspcode", reqMap.get("rspcode"));// 返回码
		respMap.put("rspmsg", reqMap.get("rspmsg"));// 交易返回信息
		respMap.put("action", reqMap.get("action"));// 银联跳转页面
		respMap.put("data", reqMap.get("data"));// 支付数据
		respMap.put("url", reqMap.get("url"));// 未使用
		respMap.put("sourceData", reqMap.get("sourceData"));// 交易返回信息
		respMap.put("channel_type", SystemConstant.CHANNEL_TYPE_API);
		respMap.put("verify_code_type", SystemConstant.VERIFY_CODE_TYPE_1);
		log.info("上海汇宜支付响应响应报文转标准化系统处理报文[{}]",respMap);
		return respMap;
	}
	
	/**
	 * 
	 * 接口: 检查会员银行卡是否签约
	 * @param dataMap
	 * @return
	 * @since 2017年12月4日
	 */
	private Map<String, Object> getChannelBankcard(Map dataMap) {
		Map<String, Object> data = null;
		try {
			data = appPayDao.getChannelBankcard(String.valueOf(dataMap.get("bankcard_uuid")),
					String.valueOf(dataMap.get("channel_No")));
		} catch (SQLException e) {
			_log.error("验证银行卡是否开通发生异常!", e);
		}
		return data;
	}
	
	/**
	 * 
	 * 接口: 保存会员银行卡签约记录
	 * @param dataMap
	 * @return
	 * @author 杨剑武
	 * @since 2017年12月5日
	 */
	private boolean saveChannelBankcard(Map dataMap,String user_agree_id,String pay_agree_id ) {
		try {
			appPayDao.saveChannelBankcard(String.valueOf(dataMap.get("bankcard_uuid")),
					String.valueOf(dataMap.get("channel_No")),user_agree_id,pay_agree_id,String.valueOf(dataMap.get("login_id")));
			return true;
		} catch (Exception e) {
			 _log.error("保存渠道银行卡开通记录发生异常!",e);
			return false;
		}
	}
	
	private Map<String, String> queryStandard(Map<String, Object> payResMap, String loc_trace_no) {
		Map<String, String> respMap = new HashMap<String, String>();
		Map<String, String> infoMap = appLogTransJnlsPayService.getTranInfo(loc_trace_no);
		respMap.put("trf_mchnt_cd", infoMap.get("trf_mchnt_cd"));// 商户编号（渠道）
		respMap.put("trf_term_id", infoMap.get("trf_term_id"));// 终端编号（渠道）
		respMap.put("custom_no", infoMap.get("custom_no"));// 客户编号（支付系统）
		respMap.put("loc_trace_no", loc_trace_no);// 本地流水号（支付系统)
		respMap.put("stlst", infoMap.get("stlst"));// 清算状态(待定)
		respMap.put("trans_at", String.valueOf(MathUtils.mul(Double.valueOf(infoMap.get("trans_at")), 100)));// 交易金额(数据库查询)
		respMap.put("midfee", String.valueOf(MathUtils.mul(Double.valueOf(infoMap.get("midfee")), 100)));// 商户手续费
		String rspcode = infoMap.get("rspcode");// 返回码
		String rspmsg = infoMap.get("rspmsg");// 交易返回信息
		if (payResMap != null && !payResMap.isEmpty()) {
			rspcode = CommonService.encapResultCode(String.valueOf(payResMap.get("resp_cd")));
			if (SystemConstant.RSPCODE_SUCCESS.equals(rspcode)) {
				String complete_dt = StringUtils.isBlank(String.valueOf(payResMap.get("tran_dt_tm"))) ? ""
						: DateUtil.toString(DateUtil.StrToDate(String.valueOf(payResMap.get("tran_dt_tm"))),
								"yyyyMMdd");
				String complete_ts = StringUtils.isBlank(String.valueOf(payResMap.get("tran_dt_tm"))) ? ""
						: DateUtil.toString(DateUtil.StrToDate(String.valueOf(payResMap.get("tran_dt_tm"))), "HHmmss");
				respMap.put("complete_dt", complete_dt);// 订单完成日期（渠道）
				respMap.put("complete_ts", complete_ts);// 订单完成时间（渠道）
				respMap.put("term_id", "");// 终端编号（支付系统）
				respMap.put("trf_trace_no", String.valueOf(payResMap.get("sys_order_id")));// 渠道方流水号（渠道）
				respMap.put("trs_stat",
						CommonService.encapRespCode(String.valueOf(payResMap.get("trade_status")), null));// 交易状态
				respMap.put("stl_dt", String.valueOf(payResMap.get("sett_dt")));// 清算日期
				respMap.put("stl_amt", "");// 结算金额
				respMap.put("stlst", CommonService.encapSettleRespCode(String.valueOf(payResMap.get("trade_status"))));// 清算状态
				respMap.put("midfee", "");// 商户手续费
				respMap.put("costfee", "");// 成本手续费
				respMap.put("pay_dt", complete_dt);// 出款日期
				respMap.put("pay_ts", complete_ts);// 出款时间
				rspcode = CommonService.encapRespCode(String.valueOf(payResMap.get("trade_status")), null);
				rspmsg = SystemConstant.RSPCODE_SUCCESS.equals(rspcode) ? SystemConstant.RSPCODE_SUCCESS_PAY
						: String.valueOf(noticeService.getRspCodeListMap().get(rspcode));
			} else {
				respMap.put("errorCode", String.valueOf(payResMap.get("resp_cd")));// 渠道返回码
				respMap.put("msg", String.valueOf(payResMap.get("resp_msg")));// 渠道返回信息
				rspcode = CommonService.encapRespCode(rspcode, null);
				rspmsg = StringUtils.isBlank(String.valueOf(payResMap.get("resp_msg")))
						? String.valueOf(noticeService.getRspCodeListMap().get(rspcode))
						: String.valueOf(payResMap.get("resp_msg"));
			}
		}

		respMap.put("rspcode", rspcode);// 返回码
		respMap.put("rspmsg", rspmsg);// 交易返回信息
		_log.info("上海汇宜支付主动查询标准报文map=[{}]", respMap);
		return respMap;
	}
	
	private Map<String, String> noticeStandard(Map<String, String> payResMap) {
		Map<String, String> standardDataMap = new HashMap<String, String>();
		standardDataMap.put("trf_mchnt_cd", "");// 商户编号（渠道）
		standardDataMap.put("trf_term_id", "");// 终端编号（渠道）
		String tran_dt_dt = StringUtils.isBlank(String.valueOf(payResMap.get("tran_dt_tm"))) ? ""
				: DateUtil.toString(DateUtil.StrToDate(String.valueOf(payResMap.get("tran_dt_tm"))), "yyyyMMdd");
		String tran_dt_ts = StringUtils.isBlank(String.valueOf(payResMap.get("tran_dt_tm"))) ? ""
				: DateUtil.toString(DateUtil.StrToDate(String.valueOf(payResMap.get("tran_dt_tm"))), "HHmmss");
		standardDataMap.put("complete_dt", tran_dt_dt);// 订单完成日期（渠道）
		standardDataMap.put("complete_ts", tran_dt_ts);// 订单完成时间（渠道）
		standardDataMap.put("custom_no", "");// 商户编号（支付系统）
		standardDataMap.put("term_id", "");// 终端编号（支付系统）
		standardDataMap.put("trf_trace_no", payResMap.get("sys_order_id"));// 渠道方流水号（渠道）
		standardDataMap.put("loc_trace_no", payResMap.get("order_id"));// 本地流水号（支付系统）

		standardDataMap.put("trs_stat", CommonService.encapRespCode(payResMap.get("trade_status"), null));// 交易状态
		String stlst = CommonService.encapSettleRespCode(payResMap.get("trade_status"));
		standardDataMap.put("stlst", stlst);// 清算状态（出款状态）
		standardDataMap.put("stl_dt", String.valueOf(payResMap.get("sett_dt")));// 清算日期
		standardDataMap.put("midfee", "");// 商户手续费
		standardDataMap.put("costfee", "");// 成本手续费
		standardDataMap.put("stl_amt", "");// 结算金额
		standardDataMap.put("trans_at", String.valueOf(MathUtils
				.mul(Double.parseDouble(String.valueOf(payResMap.get("tran_amt"))), Double.parseDouble("100"))));// 交易金额
		String rspcode = CommonService.encapRespCode(payResMap.get("trade_status"), null);
		String rspmsg = SystemConstant.RSPCODE_SUCCESS.equals(rspcode) ? SystemConstant.RSPCODE_SUCCESS_PAY
				: String.valueOf(noticeService.getRspCodeListMap().get(rspcode));
		standardDataMap.put("rspcode", rspcode);// 返回码
		standardDataMap.put("rspmsg", rspmsg);// 返回信息描述
		standardDataMap.put("pay_dt", tran_dt_dt);// 出款日期
		standardDataMap.put("pay_ts", tran_dt_ts);// 出款时间
		_log.info("上海汇宜标准化异步通知报文map=[{}]", standardDataMap);
		return standardDataMap;
	}
}
